/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * MemlogMainFrame.java
 *
 * Created on Dec 29, 2009, 5:03:42 PM
 */
package dnl.dev.memlog;

import java.awt.event.ActionEvent;
import java.io.File;
import java.net.URL;
import java.util.List;

import javax.swing.Action;
import javax.swing.ImageIcon;
import javax.swing.JOptionPane;
import javax.swing.UIManager;

import dnl.confij.apps.ApplicationConfiguration;
import dnl.dev.memlog.MemlogContext.SamplingStatus;
import dnl.dev.memlog.sampler.MemSampler;
import dnl.jexem.prcs.ProcessInfo;
import dnl.jexem.prcs.util.ProcessSelectionDialog;
import dnl.ui.FileChooserUtils;
import dnl.util.ui.WindowUtils;
import dnl.util.ui.actions.AbstractAction;

/**
 * 
 * @author daniel
 */
public class MemlogMainFrame extends javax.swing.JFrame {

	private MemlogContext currentContext;
	private SnapshotsView snapshotsView;
	private HistogramStatisticsView histogramStatisticsView;
	private ApplicationConfiguration application = new ApplicationConfiguration("memlog");

	/** Creates new form MemlogMainFrame */
	public MemlogMainFrame() {
		initComponents();
		initIcons();
		setTitle("Memlog");
		reloadRecentProjects();
		resolveSnapshotJbEnabled();
	}

	public void closeProject() {
		snapshotsView = null;
		histogramStatisticsView = null;
		viewsTabbedPane.removeAll();
		resolveSnapshotJbEnabled();
	}

	public void reloadViews() {
		if (snapshotsView != null) {
			snapshotsView.present(currentContext);
		}
		if (histogramStatisticsView != null) {
			histogramStatisticsView.present(currentContext);
		}
	}

	public void resolveSnapshotJbEnabled() {
		if (currentContext != null
				&& currentContext.getMemlogProject().getSamplingType().equals(SamplingType.MANUAL)) {
			snapshotJB.setEnabled(true);
		} else {
			snapshotJB.setEnabled(false);
		}
	}

	// ------------ UI Stuff
	// ----------------------------------------------------------------------
	private void initIcons() {
		URL iconUrl = getClass().getResource("memlog.gif");
		ImageIcon ii = new ImageIcon(iconUrl);
		this.setIconImage(ii.getImage());
	}

	/**
	 * This method is called from within the constructor to initialize the form.
	 * WARNING: Do NOT modify this code. The content of this method is always
	 * regenerated by the Form Editor.
	 */
	// <editor-fold defaultstate="collapsed"
	// <editor-fold defaultstate="collapsed"
	// <editor-fold defaultstate="collapsed"
	// <editor-fold defaultstate="collapsed"
	// desc="Generated Code">//GEN-BEGIN:initComponents
	private void initComponents() {

		viewsTabbedPane = new javax.swing.JTabbedPane();
		jToolBar1 = new javax.swing.JToolBar();
		snapshotJB = new javax.swing.JButton();
		jMenuBar1 = new javax.swing.JMenuBar();
		projectMenu = new javax.swing.JMenu();
		newProjectMI = new javax.swing.JMenuItem();
		openProjectMI = new javax.swing.JMenuItem();
		saveMI = new javax.swing.JMenuItem();
		closeMI = new javax.swing.JMenuItem();
		recentJM = new javax.swing.JMenu();
		viewMenu = new javax.swing.JMenu();
		viewSnapshotsMI = new javax.swing.JMenuItem();
		statisticsMI = new javax.swing.JMenuItem();
		snapshotsJM = new javax.swing.JMenu();
		attachSamplerMI = new javax.swing.JMenuItem();
		jMenu1 = new javax.swing.JMenu();
		jMenuItem1 = new javax.swing.JMenuItem();

		setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
		getContentPane().add(viewsTabbedPane, java.awt.BorderLayout.CENTER);

		jToolBar1.setRollover(true);

		snapshotJB.setIcon(new javax.swing.ImageIcon(getClass().getResource(
				"/dnl/dev/memlog/snapshot.icon.gif"))); // NOI18N
		snapshotJB.setFocusable(false);
		snapshotJB.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
		snapshotJB.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
		snapshotJB.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				snapshotJBActionPerformed(evt);
			}
		});
		jToolBar1.add(snapshotJB);

		getContentPane().add(jToolBar1, java.awt.BorderLayout.PAGE_START);

		projectMenu.setText("Project");

		newProjectMI.setText("New");
		newProjectMI.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				newProjectMIActionPerformed(evt);
			}
		});
		projectMenu.add(newProjectMI);

		openProjectMI.setText("Open");
		openProjectMI.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				openProjectMIActionPerformed(evt);
			}
		});
		projectMenu.add(openProjectMI);

		saveMI.setText("Save");
		saveMI.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				saveMIActionPerformed(evt);
			}
		});
		projectMenu.add(saveMI);

		closeMI.setText("Close");
		closeMI.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				closeMIActionPerformed(evt);
			}
		});
		projectMenu.add(closeMI);

		recentJM.setText("Recent");
		projectMenu.add(recentJM);

		jMenuBar1.add(projectMenu);

		viewMenu.setText("View");

		viewSnapshotsMI.setText("Snapshots");
		viewSnapshotsMI.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				viewSnapshotsMIActionPerformed(evt);
			}
		});
		viewMenu.add(viewSnapshotsMI);

		statisticsMI.setText("Histogram Statistics");
		statisticsMI.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				statisticsMIActionPerformed(evt);
			}
		});
		viewMenu.add(statisticsMI);

		jMenuBar1.add(viewMenu);

		snapshotsJM.setText("Snapshots");

		attachSamplerMI.setText("Attach Sampler");
		attachSamplerMI.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				attachSamplerMIActionPerformed(evt);
			}
		});
		snapshotsJM.add(attachSamplerMI);

		jMenuBar1.add(snapshotsJM);

		jMenu1.setText("Help");

		jMenuItem1.setText("About");
		jMenu1.add(jMenuItem1);

		jMenuBar1.add(jMenu1);

		setJMenuBar(jMenuBar1);

		pack();
	}// </editor-fold>//GEN-END:initComponents

	private void viewSnapshotsMIActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_viewSnapshotsMIActionPerformed
		if (snapshotsView == null) {
			initSnapshotView();
		}
	}// GEN-LAST:event_viewSnapshotsMIActionPerformed

	private void snapshotJBActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_snapshotJBActionPerformed
		if (currentContext != null && currentContext.getMemSampler() != null) {
			String sampleName = JOptionPane.showInputDialog("SnapshotName");
			if (sampleName != null) {
				SamplingStatus samplingStatus = currentContext.takeSample(sampleName);
				if (SamplingStatus.ERR_SAMPLE_NAME_EXISTS.equals(samplingStatus)) {
					JOptionPane.showMessageDialog(this, "Sample named '" + sampleName
							+ "' already exist.");
				}
				reloadViews();
			}
		} else {
			int yesOrNo = JOptionPane
					.showOptionDialog(
							this,
							"No Sampler attached, do you want to attach a new sampler to an existing process?",
							"", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null,
							null, null);
			if (JOptionPane.YES_OPTION == yesOrNo) {
				ProcessInfo selectedProcess = selectProcess();
				if (selectedProcess != null) {

					MemSampler memSampler = new MemSampler(String.valueOf(selectedProcess
							.getProcessID()), currentContext.getMemlogProject());
					currentContext.setMemSampler(memSampler);
					currentContext.getMemlogProject().setSamplingType(SamplingType.MANUAL);
				}
			}
		}
	}// GEN-LAST:event_snapshotJBActionPerformed

	private void attachSamplerMIActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_attachSamplerMIActionPerformed

	}// GEN-LAST:event_attachSamplerMIActionPerformed

	private void closeMIActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_closeMIActionPerformed
		closeProject();
	}// GEN-LAST:event_closeMIActionPerformed

	private void initSnapshotView() {
		if (snapshotsView == null) {
			snapshotsView = new SnapshotsView();
		}
		snapshotsView.present(currentContext);
		viewsTabbedPane.addTab(snapshotsView.getViewName(), snapshotsView);
	}

	private void loadMemlogProject(File directory) {
		MemlogProject memlogProject = MemlogProject.load(directory);
		this.currentContext = new MemlogContext(memlogProject);
		initSnapshotView();
		resolveSnapshotJbEnabled();
	}

	private void openProjectMIActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_openProjectMIActionPerformed
		File f = (File) application.getConfigObject("last.selection.dir");
		if (f != null) {
			FileChooserUtils.setLastSelectedDir(f);
		}
		File directory = FileChooserUtils.selectDirectory(this);
		if (directory == null) {
			return;
		}
		loadMemlogProject(directory);
		addRecentProjectFile(currentContext.getMemlogProject().getProjectDir());
	}// GEN-LAST:event_openProjectMIActionPerformed

	private void statisticsMIActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_statisticsMIActionPerformed
		if (histogramStatisticsView == null) {
			histogramStatisticsView = new HistogramStatisticsView();
			viewsTabbedPane.addTab(histogramStatisticsView.getViewName(), histogramStatisticsView);
			histogramStatisticsView.present(currentContext);
		}
	}// GEN-LAST:event_statisticsMIActionPerformed

	private void newProjectMIActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_newProjectMIActionPerformed
		ProcessInfo selectedProcess = selectProcess();
		if (selectedProcess != null) {
			NewProjectConfigDialog configDialog = new NewProjectConfigDialog(this, true);
			WindowUtils.centerWindowRelative(configDialog, this);
			configDialog.setVisible(true);
			if (configDialog.wasCancelled()) {
				return;
			}

			currentContext = new MemlogContext(new MemlogProject(configDialog.getProjectName()));
			MemSampler memSampler = new MemSampler(String.valueOf(selectedProcess.getProcessID()),
					currentContext.getMemlogProject());
			currentContext.setMemSampler(memSampler);
			currentContext.getMemlogProject().setSamplingType(configDialog.getSamplingType());
			currentContext.getMemlogProject().save();
			addRecentProjectFile(currentContext.getMemlogProject().getProjectDir());
			initSnapshotView();
			resolveSnapshotJbEnabled();
		}
	}// GEN-LAST:event_newProjectMIActionPerformed

	private ProcessInfo selectProcess() {
		ProcessSelectionDialog dialog = new ProcessSelectionDialog(this, true);
		dialog.showJavaProcesses();
		WindowUtils.setWindowSize(dialog, .5, .4);
		WindowUtils.centerWindowRelative(dialog, this);
		dialog.setVisible(true);
		ProcessInfo selectedProcess = dialog.getSelectedProcess();
		return selectedProcess;
	}

	private void saveMIActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_saveMIActionPerformed
		currentContext.getMemlogProject().save();
	}// GEN-LAST:event_saveMIActionPerformed

	private void addRecentProjectFile(File f) {
		application.saveConfigObject("last.selection.dir", f.getParentFile());
		application.addToFileList("recent.projects", f);
		reloadRecentProjects();
	}

	private void reloadRecentProjects() {
		List<File> fileList = application.getFileList("recent.projects");
		recentJM.removeAll();
		for (final File file : fileList) {
			Action action = new AbstractAction(file.getName()) {
				@Override
				public void actionPerformedImpl(ActionEvent e) {
					loadMemlogProject(file);
				}
			};
			recentJM.add(action);
		}
	}

	/**
	 * @param args
	 *            the command line arguments
	 */
	public static void main(String args[]) {
		try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (Exception e) {
			e.printStackTrace();
		}

		java.awt.EventQueue.invokeLater(new Runnable() {

			public void run() {
				MemlogMainFrame mmf = new MemlogMainFrame();
				WindowUtils.setWindowSize(mmf, .7, .6);
				WindowUtils.centerWindow(mmf);
				mmf.setVisible(true);
			}
		});
	}

	// Variables declaration - do not modify//GEN-BEGIN:variables
	private javax.swing.JMenuItem attachSamplerMI;
	private javax.swing.JMenuItem closeMI;
	private javax.swing.JMenu jMenu1;
	private javax.swing.JMenuBar jMenuBar1;
	private javax.swing.JMenuItem jMenuItem1;
	private javax.swing.JToolBar jToolBar1;
	private javax.swing.JMenuItem newProjectMI;
	private javax.swing.JMenuItem openProjectMI;
	private javax.swing.JMenu projectMenu;
	private javax.swing.JMenu recentJM;
	private javax.swing.JMenuItem saveMI;
	private javax.swing.JButton snapshotJB;
	private javax.swing.JMenu snapshotsJM;
	private javax.swing.JMenuItem statisticsMI;
	private javax.swing.JMenu viewMenu;
	private javax.swing.JMenuItem viewSnapshotsMI;
	private javax.swing.JTabbedPane viewsTabbedPane;
	// End of variables declaration//GEN-END:variables
}
